using System.Text.Json;
using System.Threading.Tasks;
using UniversalAdminSystem.Domian.PermissionManagement.Exceptions;
using UniversalAdminSystem.Domian.PermissionManagement.ValueObjects;

namespace UniversalAdminSystem.Infrastructure.Services;

/// <summary>
/// 权限规则文件服务
/// 职责：负责权限规则配置文件的读取、写入和文件监听
/// </summary>
public class PermissionRuleFileService : IDisposable
{
    private readonly string _configFilePath;
    private FileSystemWatcher? _fileWatcher;
    private readonly Action<Dictionary<PermissionAction, HashSet<string>>> _onConfigChanged;

    public PermissionRuleFileService(string configFilePath, Action<Dictionary<PermissionAction, HashSet<string>>> onConfigChanged)
    {
        _configFilePath = configFilePath;
        _onConfigChanged = onConfigChanged;
    }

    /// <summary>
    /// 从文件加载权限规则配置
    /// </summary>
    public Dictionary<PermissionAction, HashSet<string>> LoadFromFile()
    {
        try
        {
            if (!File.Exists(_configFilePath))
            {
                throw new FileNotFoundException($"权限规则配置文件不存在: {_configFilePath}");
            }

            // await using var stream = File.OpenRead(_configFilePath);
            var jsonContent = File.ReadAllText(_configFilePath);
            var configDict = JsonSerializer.Deserialize<Dictionary<string, List<string>>>(jsonContent) ?? throw new PermissionDomainException("权限规则配置文件格式错误");

            // 转换为领域模型格式
            var rules = configDict.ToDictionary(
                kv => Enum.Parse<PermissionAction>(kv.Key, true),
                kv => kv.Value.ToHashSet()
            );

            return rules;
        }
        catch (Exception ex) when (ex is not PermissionDomainException)
        {
            throw new PermissionDomainException($"加载权限规则配置文件失败: {ex.Message}", ex);
        }
    }

    /// <summary>
    /// 将权限规则配置写入文件
    /// </summary>
    public void SaveToFile(Dictionary<PermissionAction, HashSet<string>> rules)
    {
        try
        {
            // 转换为JSON格式
            var configDict = rules.ToDictionary(
                kv => kv.Key.ToString(),
                kv => kv.Value.ToList()
            );

            var jsonContent = JsonSerializer.Serialize(configDict, new JsonSerializerOptions 
            { 
                WriteIndented = true,
                PropertyNamingPolicy = JsonNamingPolicy.CamelCase
            });

            // 确保目录存在
            var directory = Path.GetDirectoryName(_configFilePath);
            if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
            {
                Directory.CreateDirectory(directory);
            }

            File.WriteAllText(_configFilePath, jsonContent);
        }
        catch (Exception ex)
        {
            throw new PermissionDomainException($"保存权限规则配置文件失败: {ex.Message}", ex);
        }
    }

    /// <summary>
    /// 启动文件监听（热重载）
    /// </summary>
    public void StartFileWatcher()
    {
        try
        {
            _fileWatcher?.Dispose();
            
            var directory = Path.GetDirectoryName(_configFilePath);
            var fileName = Path.GetFileName(_configFilePath);
            
            if (string.IsNullOrEmpty(directory) || string.IsNullOrEmpty(fileName))
            {
                throw new ArgumentException("配置文件路径无效");
            }

            _fileWatcher = new FileSystemWatcher(directory, fileName)
            {
                NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.CreationTime,
                EnableRaisingEvents = true
            };

            _fileWatcher.Changed += OnConfigFileChanged;
            _fileWatcher.Created += OnConfigFileChanged;
        }
        catch (Exception ex)
        {
            throw new PermissionDomainException($"启动文件监听失败: {ex.Message}", ex);
        }
    }

    /// <summary>
    /// 文件变更事件处理
    /// </summary>
    private void OnConfigFileChanged(object sender, FileSystemEventArgs e)
    {
        try
        {
            // 延迟加载，避免文件写入过程中读取
            Thread.Sleep(100);
            
            var rules = LoadFromFile();
            _onConfigChanged?.Invoke(rules);
            
            Console.WriteLine($"权限规则配置文件已重新加载: {e.FullPath}");
        }
        catch (Exception ex)
        {
            // 记录错误但不抛出异常，避免影响系统运行
            Console.WriteLine($"权限规则配置文件变更加载失败: {ex.Message}");
        }
    }

    /// <summary>
    /// 停止文件监听
    /// </summary>
    public void StopFileWatcher()
    {
        _fileWatcher?.Dispose();
        _fileWatcher = null;
    }

    public void Dispose()
    {
        StopFileWatcher();
    }
} 